#region File Header

//----------------------------------------------------------------
// Copyright (C) 2002 Stefan Kyntchev
// All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY 
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT 
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR 
// FITNESS FOR A PARTICULAR PURPOSE.
//----------------------------------------------------------------

#endregion File Header

using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using AirWeb.ApplicationTools;
using AirWeb.ApplicationTools.Common;
using AirWeb.DirectoryMgr;
using AirWeb.Support.Diagnostics;

namespace FlashBack.Web
{
	/// <summary>
	///    Summary description for ThumbNails.
	/// </summary>
	public partial class ThumbNails : PageBase
	{
		protected DataTable m_contentDataTable;
		protected ArrayList m_contentList;
		protected DirectoryHelper m_dirHelper;
		private DirectoryLister m_Lister = new DirectoryLister();

		private int m_thumbH = -1;
		private int m_thumbW = -1;

		/// <summary>
		/// Constructor
		/// </summary>
		public ThumbNails()
		{
			m_dirHelper = new DirectoryHelper();
			Page.Init += new EventHandler(Page_Init);

			//Subscribe to events from directory helper
			//The event handler class is implemented in PageBase
			m_dirHelper.StatusEvent += new StatusEventHandler(DirHelperNotifier);
		}

		/// <summary>
		/// Persistent (in a cookie) property for the number of
		/// rows per page
		/// </summary>
		private int ThumbH
		{
			get
			{
				// cache the value of the cookie
				if (m_thumbH != -1)
					return m_thumbH;

				HttpCookie c = Request.Cookies["th"];
				if (c == null)
					return 4;

				int h = Convert.ToInt16(c.Value);
				if (h > 50)
					m_thumbH = 50;
				else
					m_thumbH = h;

				return m_thumbH;
			}

			set
			{
				if (value > 50)
					value = 50;

				if (value < 1)
					value = 1;

				m_thumbH = value; // update the cache

				HttpCookie c = new HttpCookie("th", value.ToString());
				c.Expires = new DateTime(2020, 1, 1);
				Response.Cookies.Add(c);
			}
		}

		/// <summary>
		/// Persistent (in a cookie) property for the number of
		/// columns per page
		/// </summary>
		private int ThumbW
		{
			get
			{
				// cache the value of the cookie
				if (m_thumbW != -1)
					return m_thumbW;

				HttpCookie c = Request.Cookies["tw"];
				if (c == null)
					return 4;

				int w = Convert.ToInt16(c.Value);
				if (w > 20)
					m_thumbW = 20;
				else
					m_thumbW = w;

				return m_thumbW;
			}

			set
			{
				if (value > 20)
					value = 20;

				if (value < 1)
					value = 1;


				m_thumbW = value; // update the cache

				HttpCookie c = new HttpCookie("tw", value.ToString());
				c.Expires = new DateTime(2020, 1, 1);
				Response.Cookies.Add(c);
			}
		}


		/// <summary>
		/// Loads the page and processes input parameters (query or folder path)
		/// Sets the class memeber m_contentList with the items that should be
		/// displayed. 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected virtual void Page_Load(object sender, EventArgs e)
		{
			String request = Request.QueryString["path"];
			String query = Request.QueryString["qu"];

			try
			{
				if (query != null)
				{
					m_contentList = GetFilesFromSearch(query);

					if (m_contentList.Count == 0)
					{
						DisplayErrorMsg("There are no pictures that match this search criteria!");
						return;
					}

					SetNavigation(null, "qu=" + HttpUtility.UrlEncode(query));
					SetTitle(m_contentList.Count + " Pictures found");
				}
				else
				{

					RssLink.NavigateUrl = "~/RSS/RSS.ashx?path=" + request;
					m_contentList = GetFilesFromPath(request);

					if (m_contentList.Count == 0)
					{
						DisplayErrorMsg(
							"There are no pictures or movies in this album! <br> Please select another album or you can try to expand this album by clicking on the plus sign in front of it.");
						return;
					}

					SetNavigation(null, "path=" + HttpUtility.UrlEncode(request));
					SetTitle(request + " - " + m_contentList.Count + " pictures");
				}
			}
			catch (UnauthorizedAccessException ua)
			{
				throw ua; // Let the error page handle this exception
			}
			catch (Exception ex)
			{
				DisplayErrorMsg("Unable to execute the query! " + ex.Message);
				ApplicationLog.WriteError("Unable to execute the query! " + ex.Message);
				return;
			}

			// Handle CE differently
			if (Request.Browser.Platform == "WinCE")
			{
				details.Visible = false;
				title.Visible = false;
				HomeLink.Visible = true;
			}

			if (!IsPostBack)
			{
				BuildAndBind();
			}
		}

		/// <summary>
		/// Helper function. Processes the search request
		/// </summary>
		/// <param name="i_query">Search string</param>
		/// <returns>Arry of file items found by the search</returns>
		protected virtual ArrayList GetFilesFromSearch(string i_query)
		{
			return new ArrayList();
			/*IXQuery q = new IXQuery(""); // use the catalog from the configuration file
			try
			{
				q.Query(i_query);
			}
			catch (Exception exc)
			{
				COMException c = (COMException) (exc);
				throw c;
			}

			return m_dirHelper.GetPictureList(q.FileList, GetFolderType(), CurrentUser);*/
		}

		/// <summary>
		/// Helper function. Gets items from specified path
		/// </summary>
		/// <param name="i_path"></param>
		/// <returns>Arry of file items </returns>
		protected virtual ArrayList GetFilesFromPath(string i_path)
		{
			return m_dirHelper.GetPictureList(i_path, GetFolderType(), CurrentUser);
		}

		/// <summary>
		/// Sets the title of the page. Subclasses my overide
		/// </summary>
		/// <param name="i_newTitle"></param>
		protected virtual void SetTitle(string i_newTitle)
		{
			title.Text = i_newTitle.Replace("/", " > ");
		}

		/// <summary>
		/// Sets the navigation link of the page
		/// </summary>
		/// <param name="i_newTitle"></param>
		/// <param name="i_newURL"></param>
		protected virtual void SetNavigation(string i_newTitle, string i_newURL)
		{
			if (i_newTitle != null)
				slideShow.Text = i_newTitle;

			slideShow.NavigateUrl = "SlideShow.aspx?" + i_newURL;

			if (i_newURL != "")
				details.NavigateUrl = "DetailList.aspx?" + i_newURL;
			else
				details.Visible = false;
		}

		/// <summary>
		/// Helper function. Lests subclasses to determine what type of folder
		/// should the list be. Used by GetFilesFromSearch and GetFilesFromPath
		/// </summary>
		/// <returns></returns>
		protected virtual DirectoryHelper.FolderType GetFolderType()
		{
			return DirectoryHelper.FolderType.tn;
		}

		/// <summary>
		/// Builds the datatable out of the List of files returned stored in
		/// m_contentDataTable. Sets the class memeber m_contentDataTable with the
		/// resultant data table. 
		/// </summary>
		protected virtual void BuildAndBind()
		{
			m_contentDataTable = new DataTable();
			DataRow dr;
			m_contentDataTable.Columns.Add(new DataColumn("FileName", typeof (string)));
			m_contentDataTable.Columns.Add(new DataColumn("SlideName", typeof (string)));
			m_contentDataTable.Columns.Add(new DataColumn("SlideSize", typeof (string)));
			m_contentDataTable.Columns.Add(new DataColumn("SlideDate", typeof (string)));

			IEnumerator myEnumerator = m_contentList.GetEnumerator();

			while (myEnumerator.MoveNext())
			{
				FileInfo f = (FileInfo) myEnumerator.Current;
				dr = m_contentDataTable.NewRow();

				String tnpath = m_dirHelper.ReverseMapPath(f.FullName, m_dirHelper.AppPath);
				dr[0] = tnpath;

				dr[1] = GetSlideName(tnpath);

				long filesize;
				FileInfo f1 = new FileInfo(Request.MapPath(m_dirHelper.TN2OG(tnpath)));
				if (f1.Exists)
					filesize = f1.Length/1024;
				else
					filesize = 3000/1024;

				dr[2] = filesize.ToString() + " K";

				dr[3] = f1.CreationTime.ToShortDateString();

				m_contentDataTable.Rows.Add(dr);
			}

			BindToControl(m_contentDataTable);
		}

		/// <summary>
		/// Allows subclasses to bind the results of the search to different controls
		/// </summary>
		/// <param name="i_dt">DataTable to be bound to</param>
		protected virtual void BindToControl(DataTable i_dt)
		{
			// Set the page size
			ThumbsGrid.PageSize = ThumbH;

			// Show the navigation buttons
			resizebuttons.Visible = true;

			DataTable t = new DataTable();
			DataRow dr;
			int picPerRow = ThumbW;

			for (int a = 0; a != picPerRow; a++)
			{
				t.Columns.Add(new DataColumn(a.ToString(), typeof (string)));
			}

			float frows = i_dt.Rows.Count;
			frows = frows/picPerRow;
			int num_rows = (int) Math.Ceiling(frows);

			for (int b = 0; b != num_rows; b++)
			{
				dr = t.NewRow();

				for (int a = 0; a != picPerRow; a++)
				{
					int curr = (b*picPerRow) + a;
					dr[a] = curr.ToString();
				}

				t.Rows.Add(dr);
			}

			ThumbsGrid.DataSource = new DataView(t);
			ThumbsGrid.DataBind();
		}

		/// <summary>
		/// Invoked for each row when the grid control binds its content
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void onRowBound(object sender, DataGridItemEventArgs e)
		{
			if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
			{
				Image i = new Image();

				for (int a = 0; a != e.Item.Cells.Count; a++)
				{
					ReplaceCellContent(e.Item.Cells[a]);
				}
			}
		}

		/// <summary>
		/// Replaces the index put in the table cell by BindToControl with the real image
		/// of the picture. This is renders how a single slide will look like.
		/// </summary>
		/// <param name="i_c"></param>
		private void ReplaceCellContent(TableCell i_c)
		{
			string itemno = i_c.Text;
			int itn = Convert.ToInt16(itemno);

			if (itn >= m_contentDataTable.Rows.Count)
			{
				i_c.Text = "";
			}
			else
			{
				HtmlGenericControl div = new HtmlGenericControl("div");
				div.Attributes["class"] = "thumbSlide";
				div.Attributes["Align"] = "center";
				div.Attributes["VAlign"] = "middle";

				HyperLink h = new HyperLink();
				h.Target = "_new";
				h.ToolTip = "Click to open this picture in a new window (" + m_contentDataTable.Rows[itn]["SlideSize"] +
				            "). Taken on " + m_contentDataTable.Rows[itn]["SlideDate"] + ")";
				h.NavigateUrl = m_contentDataTable.Rows[itn]["SlideName"].ToString();

				Image i = new Image();

				i.CssClass = "Thumb";
				i.Attributes["onmouseover"] = "this.className='ThumbHi'";
				i.Attributes["onmouseout"] = "this.className='Thumb'";

				string file = m_contentDataTable.Rows[itn]["FileName"].ToString();

				// Provide the correct thumbnail for images and movies
				if (!CommonHelper.IsMovie(file))
					i.ImageUrl = file;
				else
				{
					// Verify that we were able to get the thumbnail image for the movie
					file = Path.ChangeExtension(file, "jpg");
					if (File.Exists(Server.MapPath(file)))
						i.ImageUrl = file;
					else
						i.ImageUrl = "images/movie.gif";
				}

				i_c.Controls.Clear();

				div.Controls.Add(h);

				//Label l = new Label();
				//l.CssClass = "searchBody";
				//l.Text = "<br>" + Path.GetFileName(m_contentDataTable.Rows[itn]["SlideName"].ToString());

				h.Controls.Add(i);
				//h.Controls.Add(l);
				//i_c.Controls.Add(div);
				i_c.Controls.Add(h);
			}
		}

		/// <summary>
		/// Ivoked when the user selects a different page.
		/// Used by the control paging mechanism.
		/// </summary>
		/// <param name="Sender"></param>
		/// <param name="e"></param>
		protected void ChangePageIndex(object Sender, DataGridPageChangedEventArgs e)
		{
			ThumbsGrid.CurrentPageIndex = e.NewPageIndex;
			BuildAndBind();
		}

		/// <summary>
		/// Allows subclasses to determine what path is stored in the data table
		/// </summary>
		/// <param name="i_path"></param>
		/// <returns></returns>
		protected virtual string GetSlideName(string i_path)
		{
			string r = m_dirHelper.TN2OG(i_path);
			return m_dirHelper.UrlEncodeFilePath(r);
		}

		/// <summary>
		/// Handler for page resizing 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void OnResize(object sender, CommandEventArgs e)
		{
			String sc = e.CommandArgument.ToString();

			switch (sc)
			{
				case "left":
					--ThumbW;
					break;

				case "right":
					++ThumbW;
					break;

				case "up":
					--ThumbH;
					break;

				case "down":
					++ThumbH;
					break;
			}

			ThumbsGrid.CurrentPageIndex = 0;
			BuildAndBind();
		}

		/// <summary>
		/// Displays an error message in the middle of the screen
		/// </summary>
		/// <param name="i_msg"></param>
		protected virtual void DisplayErrorMsg(string i_msg)
		{
			Message.Visible = true;
			ThumbsGrid.Visible = false;
			MsgLabel.Text = i_msg;
			slideShow.Visible = false;
		}

		protected void Page_Init(object sender, EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP+ Windows Form Designer.
			//
			InitializeComponent();
		}

		/// <summary>
		///    Required method for Designer support - do not modify
		///    the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
		}
	}
}